//
//  UIViewController+HKExtension.m
//  HKProject
//
//  Created by 胡锦涛 on 2018/7/27.
//  Copyright © 2018年 胡锦涛. All rights reserved.
//

#import "UIViewController+HKExtension.h"
#import "HKMacro.h"
#import <objc/runtime.h>
@implementation UIViewController (HKExtension)
///Category添加Bool属性
- (BOOL)hk_hideNavBar{
    return [objc_getAssociatedObject(self, @selector(hk_hideNavBar)) boolValue];
}
- (void)setHk_hideNavBar:(BOOL)hk_hideNavBar {
     objc_setAssociatedObject(self, @selector(hk_hideNavBar), @(hk_hideNavBar), OBJC_ASSOCIATION_ASSIGN);
}


+ (void)load {
    NSString *className = NSStringFromClass(self.class);
    NSLog(@"className %@", className);
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        [self hk_changeSel:@selector(viewWillAppear:) toSel:@selector(HKViewWillAppear:)];
        [self hk_changeSel:@selector(viewWillDisappear:) toSel:@selector(HKViewWillDisappear:)];
        [self hk_changeSel:@selector(viewDidAppear:) toSel:@selector(HKViewDidAppear:)];
    });
    
}
+ (void)hk_changeSel:(SEL)sel toSel:(SEL)tosel{
    
    Class class = [self class];
    
    SEL originalSelector = sel;
    SEL swizzledSelector = tosel;
    
    Method originalMethod = class_getInstanceMethod(class, originalSelector);
    Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
    
    BOOL didAddMethod =
    class_addMethod(class,
                    originalSelector,
                    method_getImplementation(swizzledMethod),
                    method_getTypeEncoding(swizzledMethod));
    
    if (didAddMethod) {
        class_replaceMethod(class,
                            swizzledSelector,
                            method_getImplementation(originalMethod),
                            method_getTypeEncoding(originalMethod));
    } else {
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
}
-(void)HKViewDidAppear:(BOOL)animated{
    for (UIView * subview in self.view.subviews) {
        if ([subview respondsToSelector:@selector(setExclusiveTouch:)]) {
            [subview setExclusiveTouch:YES];
        }
    }
    [self HKViewDidAppear:animated];
}
- (void)HKViewWillAppear:(BOOL)animated{
    
    NSLog(@"HK_ViewWillAppear:----------------------%@",[self class]);
    [self HKViewWillAppear:animated];
}

- (void)HKViewWillDisappear:(BOOL)animated{
    
    NSLog(@"HK_ViewWillDisAppear:----------------------%@",[self class]);
    [self HKViewWillDisappear:animated];
}

///设置NavBarItem字体颜色
- (void)hk_setNavBarTextColor:(UIColor*)color {
    self.navigationController.navigationBar.tintColor = color == nil ? [UIColor blackColor] : color;
}

///设置NavBar背景颜色
- (void)hk_setNavBarBgColor:(UIColor*)bgColor {
    self.navigationController.navigationBar.barTintColor = bgColor == nil ? [UIColor whiteColor] : bgColor;
}

///设置导航条是否半透明
- (void)hk_setNavTranslucent:(BOOL)isTranslucent {
    if (isTranslucent) {
        self.navigationController.navigationBar.translucent = YES;
        //设置背景透明图片
        [self.navigationController.navigationBar setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault];
        //去掉 bar 下面有一条黑色的线
        [self.navigationController.navigationBar setShadowImage:[[UIImage alloc] init]];
    }else {
        // 重置导航透明度设置，不影响其他页面
        self.navigationController.navigationBar.translucent = NO;
        [self.navigationController.navigationBar setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
        [self.navigationController.navigationBar setShadowImage:nil];
    }
}

///导航条设置是否隐藏
- (void)hk_setNavBarHidden:(BOOL)isHide {
    if (isHide) {
        self.navigationController.navigationBar.hidden = YES;
        [self.navigationController setNavigationBarHidden:YES animated:NO];
    }else {
        self.navigationController.navigationBar.hidden = NO;
        [self.navigationController setNavigationBarHidden:NO animated:NO];
    }
}

///状态栏设置是否隐藏
/*
 info.plist文件中，View controller-based status bar appearance项设为YES，则View controller对status bar的设置优先级高于application的设置。
 View controller-based status bar appearance项设为NO，则以application的设置为准，view controller的prefersStatusBarHidden方法无效，是根本不会被调用的。
 */

- (void)hk_setStatusBarHidden:(BOOL)isHide {
    if (isHide) {
        [self prefersStatusBarHidden];
        [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
    }else {
        [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];
    }
}

///状态栏-旋转方向设置
- (void)hk_setStatusBarOrientation:(UIInterfaceOrientation)orientation {
    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft];
}

///设置状态栏字体颜色
- (void)hk_setStatusBarTextColor:(UIColor *)color {
    UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
    if ([statusBar respondsToSelector:@selector(setBackgroundColor:)]) {
        statusBar.backgroundColor = color;
    }
}

///设置状态栏背景颜色
- (void)hk_setStatusBarBackgroundColor:(UIColor *)color {
    UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
    if ([statusBar respondsToSelector:@selector(setBackgroundColor:)]) {
        statusBar.backgroundColor = color;
    }
}

///避免self.view在nav下面
- (void)hk_adjustNav{
    self.extendedLayoutIncludesOpaqueBars = NO;
    self.edgesForExtendedLayout = NO;
}

- (UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent;
}

///Present
- (void)hk_present:(UIViewController*)vc {
    if ([self isKindOfClass:[UINavigationController class]]) {
        UIViewController *v = ((UINavigationController *)self).viewControllers.lastObject;
        [v presentViewController:vc animated:YES completion:nil];
    }else{
        [self presentViewController:vc animated:YES completion:nil];
    }
}

///返回事件
- (void)hk_back {
    NSArray *viewcontrollers=self.navigationController.viewControllers;
    if (viewcontrollers.count>1) {
        if ([viewcontrollers objectAtIndex:viewcontrollers.count-1]==self) {
            //push方式
            [self.navigationController popViewControllerAnimated:YES];
        }
    }else{
        //present方式
        [self dismissViewControllerAnimated:YES completion:nil];
    }
}

///Dismiss
- (void)hk_dismiss{
    [self dismissViewControllerAnimated:YES completion:nil];
}

///回到根视图
- (void)hk_backToRoot {
    NSArray *viewcontrollers=self.navigationController.viewControllers;
    if (viewcontrollers.count>1) {
        if ([viewcontrollers objectAtIndex:viewcontrollers.count-1]==self) {
            //push方式
            [self.navigationController popToRootViewControllerAnimated:YES];
        }
    }else{
        //present方式
        UIViewController *rootVC = self.presentingViewController;
        while (rootVC.presentingViewController) {
            rootVC = rootVC.presentingViewController;
        }
        [rootVC dismissViewControllerAnimated:YES completion:nil];
    }
}

///设置屏幕旋转方向 UIInterfaceOrientationPortrait
- (void)hk_setOrientation:(UIInterfaceOrientation)orientation
{
    if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {
        SEL selector             = NSSelectorFromString(@"setOrientation:");
        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];
        [invocation setSelector:selector];
        [invocation setTarget:[UIDevice currentDevice]];
        int val                  = orientation;
        [invocation setArgument:&val atIndex:2];
        [invocation invoke];
    }
}

///竖屏
- (void)hk_portraitScreen
{
    [self hk_setOrientation:UIInterfaceOrientationPortrait];
}

///横屏
- (void)hk_landscapScreen
{
    [self hk_setOrientation:UIInterfaceOrientationLandscapeRight];
}

///设置物理设备方向 | UIInterfaceOrientationLandscapeLeft
- (void)hk_changeDeviceOriention:(UIInterfaceOrientation)deviceOriention {
    
    NSNumber *orientationUnknown = [NSNumber numberWithInt:UIInterfaceOrientationUnknown];
    [[UIDevice currentDevice] setValue:orientationUnknown forKey:@"orientation"];
    
    NSNumber *orientationTarget = [NSNumber numberWithInt:deviceOriention];
    [[UIDevice currentDevice] setValue:orientationTarget forKey:@"orientation"];
}

///物理设备方向-竖屏
- (void)hk_devicePortrait
{
    [self hk_changeDeviceOriention:UIInterfaceOrientationPortrait];
}

///物理设备方向-横屏
- (void)hk_deviceLandscap
{
    [self hk_changeDeviceOriention:UIInterfaceOrientationLandscapeRight];
}
/*界面跳转动画*/
- (void)hk_makeTransionWith:(UIViewController*)vc;  {
    UIWindow * mainWindow = [[[UIApplication sharedApplication] delegate] window];
    [UIWindow transitionWithView:mainWindow duration:1 options:UIViewAnimationOptionTransitionCrossDissolve animations:nil completion:nil];
    mainWindow.rootViewController = vc;
}

- (void)hk_linearTransionTo:(UIViewController *)destination {
    destination.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
    [self presentViewController:destination animated:NO completion:nil];
}

- (UIViewController *)hk_presentedViewController
{
    UIViewController *appRootVC = [UIApplication sharedApplication].keyWindow.rootViewController;
    UIViewController *topVC = appRootVC;
    if (topVC.presentedViewController) {
        topVC = topVC.presentedViewController;
        return [self presentedViewController:topVC];
    }
    return topVC;
}

- (UIViewController *)presentedViewController:(UIViewController *)ctr
{
    if (ctr.presentedViewController)
    {
        ctr = ctr.presentedViewController;
        return [self presentedViewController:ctr];
    }
    return ctr;
}

#pragma mark - Alert 相关
- (void)hk_alertWithTitle:(NSString *)title message:(NSString *)message cancelTitle:(NSString *)cancelTitle cancelHandler:(void(^)(void))cancelHandler confirmTitle:(NSString *)confirmTitle confirmHandler:(void(^)(void))ensureHandler {
    UIAlertController* alert = [UIAlertController alertControllerWithTitle:title
                                                                   message:message
                                                            preferredStyle:UIAlertControllerStyleAlert];
    
    UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:cancelTitle style:UIAlertActionStyleCancel
                                                          handler:^(UIAlertAction * _Nonnull action) {
                                                              if (cancelHandler) {
                                                                  cancelHandler();
                                                              }
                                                          }];
    
    [alert addAction:defaultAction];
    UIAlertAction* otherAction = [UIAlertAction actionWithTitle:confirmTitle style:UIAlertActionStyleDestructive
                                                        handler:^(UIAlertAction * _Nonnull action) {
                                                            if (ensureHandler) {
                                                                ensureHandler();
                                                            }
                                                        }];
    
    [alert addAction:otherAction];
    [self presentViewController:alert animated:YES completion:nil];
}

- (void)hk_alertWithTitle:(NSString *)title
                          message:(NSString *)message
                     confirmTitle:(NSString *)confirmTitle
                          handler:(void(^)(void))handler {
    
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
    
    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:confirmTitle style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        
        if (handler) {
            handler();
        }
    }];
    
    [alert addAction:cancelAction];
    [self presentViewController:alert animated:YES completion:nil];
}

///双按键的 alertView
- (void)hk_alertWithTitle:(NSString *)title
                          message:(NSString *)message
                      cancelTitle:(NSString *)cancelTitle
                     defaultTitle:(NSString *)defaultTitle
                         distinct:(BOOL)distinct
                           cancel:(void(^)(void))cancel confirm:(void(^)(void))confirm {
    
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
    
    if (distinct) {
        // 左浅右深
        UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:cancelTitle style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
            if (cancel) {
                cancel();
            }
        }];
        [alert addAction:cancelAction];
    } else {
        UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:cancelTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            if (cancel) {
                cancel();
            }
        }];
        [alert addAction:cancelAction];
    }
    
    
    UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:defaultTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        if (confirm) {
            confirm();
        };
    }];
    
    [alert addAction:defaultAction];
    
    [self presentViewController:alert animated:YES completion:nil];
}

/// Alert  任意多个按键 返回选中的 buttonIndex 和 buttonTitle
- (void)hk_alertWithTitle:(NSString *)title
                      message:(NSString *)message
                 actionTitles:(NSArray *)actionTitles
               preferredStyle:(UIAlertControllerStyle)preferredStyle
                      handler:(void(^)(NSUInteger buttonIndex, NSString *buttonTitle))handler {
    
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:preferredStyle];
    
    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        handler(0, @"取消");
    }];
    [alert addAction:cancelAction];
    
    for (int i = 0; i < actionTitles.count; i ++) {
        
        UIAlertAction *confimAction = [UIAlertAction actionWithTitle:actionTitles[i] style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            handler((i + 1), actionTitles[i]);
        }];
        [alert addAction:confimAction];
    }
    
    [self presentViewController:alert animated:YES completion:nil];
}

#pragma mark - 通用提示Alert
- (void)hk_showMessage:(NSString*)message {
    [self hk_alertWithTitle:@"温馨提示" message:message confirmTitle:@"好的" handler:^{
        
    }];
}

#pragma mark - UINavigationControllerDelegate-完美解决navigationBar隐藏/显示
- (void)navigationController:(UINavigationController*)navigationController willShowViewController:(UIViewController*)viewController animated:(BOOL)animated {
    
    if(viewController == self && self.hk_hideNavBar){
        [navigationController setNavigationBarHidden:YES animated:YES];
    }else{
        
        //系统相册继承自 UINavigationController 这个不能隐藏 所有就直接return
        if ([navigationController isKindOfClass:[UIImagePickerController class]]) {
            return;
        }
        
        //不在本页时，显示真正的navbar
        [navigationController setNavigationBarHidden:NO animated:YES];
        //当不显示本页时，要么就push到下一页，要么就被pop了，那么就将delegate设置为nil，防止出现BAD ACCESS
        //之前将这段代码放在viewDidDisappear和dealloc中，这两种情况可能已经被pop了，self.navigationController为nil，这里采用手动持有navigationController的引用来解决
        if(navigationController.delegate == self){
            //如果delegate是自己才设置为nil，因为viewWillAppear调用的比此方法较早，其他controller如果设置了delegate就可能会被误伤
            navigationController.delegate = nil;
        }
    }
}

- (void)hk_systemShareContent:(NSString*)content {
    // 1、设置分享的内容，并将内容添加到数组中
    NSArray *activityItemsArray = @[content];
    NSArray *activityArray = @[];
    
    // 2、初始化控制器，添加分享内容至控制器
    UIActivityViewController *activityVC = [[UIActivityViewController alloc]initWithActivityItems:activityItemsArray applicationActivities:activityArray];
    activityVC.modalInPopover = YES;
    // 3、设置回调
    if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0) {
        // ios8.0 之后用此方法回调
        UIActivityViewControllerCompletionWithItemsHandler itemsBlock = ^(UIActivityType __nullable activityType, BOOL completed, NSArray * __nullable returnedItems, NSError * __nullable activityError){
            HKLog(@"activityType == %@",activityType);
            if (completed == YES) {
                HKLog(@"completed");
            }else{
                HKLog(@"cancel");
            }
        };
        activityVC.completionWithItemsHandler = itemsBlock;
    }
    // 4、调用控制器
    [self presentViewController:activityVC animated:YES completion:nil];
}
@end
